home *** CD-ROM | disk | FTP | other *** search
- /*
- From ndsuvm1!cunyvm!psuvm.bitnet!ukma!husc6!think!ephraim Tue Feb 23 08:56:14 CST 1988
- Article 32 of comp.sys.mac.programmer:
- Path: ndsuvax!ndsuvm1!cunyvm!psuvm.bitnet!ukma!husc6!think!ephraim
- >From: ephraim@think.COM (ephraim vishniac)
- Newsgroups: comp.sys.mac.programmer
- Subject: A Custom WDEF
- Message-ID: <16995@think.UUCP>
- Date: 22 Feb 88 15:59:09 GMT
- Sender: usenet@think.UUCP
- Reply-To: ephraim@think.UUCP (ephraim vishniac)
- Organization: Thinking Machines Corporation, Cambridge, MA
- Lines: 345
-
- Since mentioning in a comp.sys.mac article that I had seen a circular
- window on the Mac, several people have asked for source code or a copy
- of the program. Following is the help text from the program called
- "Windows Demo." The program features a variety of unusual window
- types, and the help text explains how they are produced.
- I will send the actual program (and this text) to info-mac, so that
- internet users can retrieve it from sumex. Even though it was
- compiled long ago with Megamax C, the program now runs on a Mac II - I
- just patched all those nasty 02B6's to 0A78's and there's no problem
- any more.
- ---------------------- Start of Help Text -------------------------
- Program by Richard Koch
- Department of Mathematics
- University of Oregon
- Eugene, Oregon 97403
- The Macintosh toolbox contains routines which move windows, resize
- them, and so forth. These routines are quite complicated; when a
- window is moved, the system must erase the old version of the window,
- draw the window in its new position, draw newly exposed portions of
- other windows, and recalculate the visible portions of all windows. It
- is natural to suppose that the toolbox routines which do these things
- assume that windows are rectangular, but in fact the routines have
- been written to handle windows of any shape whatever.
- Most Macintosh programmers use one of the six predefined windows at
- the left; these windows are basically rectangular (the final window
- has curved corners). But it is easy to define other window shapes.
- Windows can have holes in the middle, curved borders, fancy frames,
- and other unusual features.
- Some Macintosh users believe that the computer keeps a complete
- copy of each window in memory even when the window is not visible on
- the screen. But that is not correct. The Macintosh knows how to draw
- window frames and redraws portions of these frames when they become
- visible. But the contents of windows are the responsibility of
- programs; the Macintosh issues a warning when a previously hidden
- portion of a window becomes visible, and the program does whatever it
- wishes. The program you are running is lazy and erases windows
- entirely when new portions become visible; by turning this feature
- off, you can see that the toolbox erases each newly visible portion of
- a window before reporting that it should be redrawn.
- Since round windows require extensive calculations, they slow the
- system down enough to let us see the window moving algorithms in
- operation. If a window is moved from one portion of the screen to
- another, the toolbox directly moves screen memory and no redrawing is
- necessary. It is easier for the toolbox to make this pixel move when
- the window moves up than when the window moves down. If a window is
- moved part way off the screen and later moved back on, the toolbox
- copies those portions still on the screen by a direct memory move, but
- remaining portions of the window frame and contents must be redrawn.
- To produce an unusual window, it is only necessary to write one
- function of the form
- long MyWindow(varCode, theWindow, message, param)
- int varCode, message; WindowPtr theWindow; long param;
- This function is called by the toolbox when the toolbox needs to know
- the shape of the entire window or its content region, when it needs to
- know where the mouse went down in the window, or when it needs to draw
- the window frame. All other Macintosh window operations are handled
- automatically without help from the programmer. The parameter
- "message" explains what operation to perform, and the parameter
- "param" contains additional information for some requests. It is
- possible to create several related windows with only minor variations
- in appearance; the parameter varCode explains which variant to use.
- This parameter must be between 0 and 15.
- The code for "MyWindow" can be put in the main program code area,
- or it can be placed in a resource of type WDEF. In the program you are
- running, code for the rectangular and square windows is included with
- other program code, but code for the round windows is in a WDEF
- resource with ID #128.
- The Macintosh system contains two WDEF resources with ID's 0 and 1 which define all of the standard windows on the left. The firs
- When the Macintosh is running a program and needs a resource, it
- first searches the program file for the resource and only searches the
- system file if the resource cannot be found in the program file.
- Consequently, it is possible to trick programs so they will produce
- round windows rather than rectangular windows. Using ReEdit, cut the
- entire WDEF resource from the program you are running and paste it
- into MacWrite. Then change its resource ID # from 128 to 0. When you
- run the resulting MacWrite, it will use round windows for all
- operations. (Warning: Text written into MacWrite will disappear under
- the frame of the round window, and the "OK" box for some dialogs will
- be hidden beyond the window frame. Often a dialog will accept "RETURN"
- as the equivalent of clicking on "OK," but otherwise you will be stuck
- and have to reset the computer.)
- The round window WDEF can be pasted into the FINDER itself,
- yielding a round directory.
- It is easy to use the round window from this program in your own
- programs. Simply copy WDEF #128 into your resources and change its ID
- number as appropriate. Your resource code should also contain a window
- definition somewhat like
- TYPE WIND
- ,128 ; window resource ID
- First Round Window ; window title
- 40 80 120 300 ; top left bottom right
- Visible NoGoAway ; window status
- 2048 ; WindProcID (see below)
- 0 ; RefCon
- The actual program code will create this window in the usual way
- using a line like
- wp = GetNewWindow(128, wStorage, -1L);
- Of course this last line will be different if you are using another
- language, but everything else will be the same.
- The only strange feature here is the rule for assigning the
- WindProcID number. This number should equal sixteen times the WDEF
- resource number of the appropriate window definition code plus the
- varCode of the window variant. For example, the first five windows
- pictured at the left are produced by WDEF #0 in the system file with
- varCodes 0 through 5, so their WindProcID's are 0 through 5. The sixth
- window to the left is produced by WDEF #1 in the system file using
- varCode 0, so its WindProcID is 16.
- The WDEF for round windows allows sixteen possible variants. The
- rightmost bit in the variant number is 1 if the window has a title and
- 0 otherwise. The next bit left is 1 if the window has no grow box and
- 0 otherwise. The next bit is 1 if the window has a fancy woven frame
- and 0 otherwise. The final left bit is 1 if the title appears on the
- top and 0 if it appears on the bottom. So the variant number for a
- window with a title, grow box, fancy frame, and title at the top is:
- 1 + 2 * 0 + 4 * 1 + 8 * 1 = 13.
- If you want to change the appearance of the round windows from this
- program, you will have to rewrite the code for "MyWindow." Below is
- this code, written using Megamax C.*/
- //#include <qd.h>
- //#include <qdvars.h>
- //#include <win.h>
- //#include <menu.h>
- //#include <event.h>
- //#include <dialog.h>
-
- /* Optional:
- pascal long myWindowWDEF(int varCode, WindowPeek theWindow, int message, long param)
- */
-
- pascal long main(int varCode, WindowPeek theWindow, int message, long param)
- {
- typedef Rect *RPtr;
- Rect r, rclose[4], rgrow, rtitle;
- int i,j,k;
- Point p;
- GrafPtr temp;
- PenState pnState;
- RgnHandle hstructure, hcontent, frame, htitle;
- Pattern pat;
- Str255 title;
- GetPort(&temp); SetPort((GrafPtr)theWindow);
- r = (*((GrafPtr)theWindow)).portRect;
- i = r.right - r.left; j = r.bottom - r.top;
- if (i > j)
- i = j;
- r.left = 0; r.top = 0;
- LocalToGlobal(&(r));
- SetPort(temp);
- r.bottom = r.top + i; r.right = r.left + i;
-
- SetRect(&rclose[0],r.left + 3,r.top + i/2 - 6,
- r.left + 14,r.top + i/2 + 5);
-
- SetRect(&rclose[1],r.right - 14,r.top + i/2 -6,
- r.right -3,r.top + i/2 + 5);
-
- SetRect(&rclose[2],r.left + i/2 - 6,r.top + 3,
- r.left + i/2 + 5,r.top + 14);
-
- SetRect(&rclose[3],r.left + i/2 - 6,r.bottom -14,
- r.left + i/2 + 5,r.bottom -3);
-
- rgrow.right = r.left + i/2 + ((i/2)*10)/14;
- rgrow.bottom = r.top + i/2 + ((i/2)*10)/14;
- rgrow.left = rgrow.right - (9*141)/100;
- rgrow.top = rgrow.bottom - (9*141)/100;
- for (k = 0; k < 256; k++) title[k] =
- *(*((*theWindow).titleHandle) + k);
- // ptocstr(&title);
- j = StringWidth(&title) / 2 + 15;
- rtitle.left = r.left + i/2 - j;
- rtitle.right = rtitle.left + j + j;
- if (varCode & 0x0008)
- {
- rtitle.top = r.top;
- rtitle.bottom = r.top + 16;
- }
- else
- {
- rtitle.bottom = r.bottom;
- rtitle.top = r.bottom - 16;
- }
- p.v = HiWord(param); p.h = LoWord(param);
- hstructure = (*theWindow).strucRgn;
- hcontent = (*theWindow).contRgn;
- switch(message)
- {
- case 0:
- if ((*theWindow).visible)
- {
- if (param == 0L)
- {
- GetPenState(&pnState);
- PenSize(18,18);PenMode(patBic);
- FrameOval(&r);
- SetPenState(&pnState);
- if (((*theWindow).hilited) && (varCode &0x0004))
- {
- pat[0] = 0xF8; pat[1] = 0x74;
- pat[2] = 0x22; pat[3] = 0x47;
- pat[4] = 0x8F; pat[5] = 0x17;
- pat[6] = 0x22; pat[7] = 0x71;
- FrameOval(&r);InsetRect(&r,1,1);
- FrameOval(&r);InsetRect(&r,1,1);
- frame = NewRgn();OpenRgn();
- FrameOval(&r);InsetRect(&r,13,13);
- FrameOval(&r);CloseRgn(frame);
- FillRgn(frame,&pat);DisposeRgn(frame);
- FrameOval(&r);InsetRect(&r,1,1);
- FrameOval(&r);
- } //• if hitlited and varcode at 0004
- else
- {
- FrameOval(&r);InsetRect(&r,3,3);
- if ((*theWindow).hilited)
- for (i = 0; i < 6; i++)
- {
- FrameOval(&r);InsetRect(&r,2,2);
- }
- else
- InsetRect(&r,12,12);
- InsetRect(&r,1,1);FrameOval(&r);
- }
- if (((*theWindow).hilited) && ((*theWindow).goAwayFlag))
- {
- for (i = 0; i < 4; i++)
- {
- EraseRect(&rclose[i]);
- FrameRect(&rclose[i]);}
- }
- if (((*theWindow).hilited) && ((varCode & 0x0002) == 0))
- {
- EraseRect(&rgrow); FrameRect(&rgrow);}
- if (varCode & 0x0001)
- {
- EraseRect(&rtitle);FrameRect(&rtitle);
- if ((*theWindow).hilited)
- {
- InsetRect(&rtitle,1,1);
- FrameRect(&rtitle);
- InsetRect(&rtitle,-1,-1);
- MoveTo(rtitle.left + 15,
- rtitle.top + 13);
- DrawString(&title);
- }
- }
- } //• if hilited and varcode at 0002
- else
- if (param == 4L)
- {
- GetPenState(&pnState);
- PenMode(patXor);
- for (i = 0; i < 4; i++)
- if ((i == 2) && (varCode & 1) && (varCode & 8))
- ; //• do nada!
- else
- if ((i == 3) && (varCode & 1) && !(varCode & 8))
- ; //• do nada!
- else
- {
- MoveTo(rclose[i].left+2,
- rclose[i].top+2);
- Line(6,6);
- MoveTo(rclose[i].left+2,
- rclose[i].bottom-3);
- Line(6,-6);
- MoveTo(rclose[i].left+1,
- rclose[i].top + 5);
- Line(8,0);
- MoveTo(rclose[i].left+5,
- rclose[i].top+1);
- Line(0,8);
- InsetRect(&rclose[i],4,4);
- EraseRect(&rclose[i]);
- }
- SetPenState(&pnState);
- } //• if param 4L.
- } //if hilited and goAwayFlag.
- } //• if param 0L.
- } //• if visible.
- return(0L);
- break;
-
- case 1:
- if (PtInRgn(p,hcontent))
- return(1L);
- else
- if ((PtInRect(p,&rclose[0])) &&
- ((*theWindow).goAwayFlag) &&
- ((*theWindow).hilited))
- return(4L);
- else
- if ((PtInRect(p,&rclose[1])) &&
- ((*theWindow).goAwayFlag) &&
- ((*theWindow).hilited))
- return(4L);
- else
- if ((PtInRect(p,&rclose[2])) &&
- ((*theWindow).goAwayFlag) &&
- ((*theWindow).hilited) &&
- (!((varCode & 1) &&
- (varCode & 8))))
- return(4L);
- else
- if ((PtInRect(p,&rclose[3])) &&
- ((*theWindow).goAwayFlag) &&
- (!((varCode & 1) &&
- !(varCode & 8))) &&
- ((*theWindow).hilited))
- return(4L);
- else
- if ((PtInRect(p,&rgrow)) &&
- ((varCode & 0x0002) == 0) &&
- ((*theWindow).hilited))
- return(3L);
- else
- if (PtInRgn(p, hstructure))
- return(2L);
- else
- return(0L);
- break;
-
- case 2:
- SetEmptyRgn(hstructure);
- OpenRgn();
- FrameOval(&r);
- CloseRgn(hstructure);
- if (varCode & 0x0001)
- {
- htitle = NewRgn();
- RectRgn(htitle, &rtitle);
- UnionRgn(hstructure, htitle, hstructure);
- DisposeRgn(htitle);
- }
- InsetRect(&r,18,18);
- SetEmptyRgn(hcontent);
- OpenRgn();
- FrameOval(&r);
- CloseRgn(hcontent);
- break;
-
- case 3:
- return(0L);
- break;
-
- case 4:
- return(0L);
- break;
-
- case 5:
- r = *(RPtr)param;
- i = r.right - r.left;
- j = r.bottom - r.top;
- if (i > j) i = j;
- r.right = r.left + i;
- r.bottom = r.top + i;
- FrameOval(&r); return(0L);
- break;
-
- case 6:
- return(0L);
- break;
- } //• switch
- } /*
- ---------------------- End of Help Text ---------------------------------
- Ephraim Vishniac ephraim@think.com
- Thinking Machines Corporation / 245 First Street / Cambridge, MA 02142-1214
- */
-
-